package com.sniff.atp.utils;

import com.alibaba.fastjson2.JSONObject;
import com.sniff.atp.constant.config.DBConnection;
import com.sniff.atp.dto.ContentDTO;
import com.sniff.atp.enums.sql.SniffSql;
import com.sniff.atp.exception.BussinessException;
import com.sniff.atp.exception.enums.ErrorEnum;
import org.apache.commons.lang3.StringUtils;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class DBUtil {
    private DBUtil() {}

    public static JSONObject selectOne(String alias, ContentDTO... contents) {
        SniffSql sniffSql = SniffSql.getSniffSQL(alias);
        if (Objects.isNull(sniffSql)) {
            throw new BussinessException(ErrorEnum.SQL_ERROR);
        }
        return selectOne(sniffSql.getDbName(), sniffSql.getSql(), contents);
    }

    public static List<JSONObject> select(String alias, ContentDTO... contents) {
        SniffSql sniffSql = SniffSql.getSniffSQL(alias);
        if (Objects.isNull(sniffSql)) {
            throw new BussinessException(ErrorEnum.SQL_ERROR);
        }
        return select(sniffSql.getDbName(), sniffSql.getSql(), contents);
    }

    public static Integer insertOrUpdate(String alias, ContentDTO... contents) {
        SniffSql sniffSql = SniffSql.getSniffSQL(alias);
        if (Objects.isNull(sniffSql)) {
            throw new BussinessException(ErrorEnum.SQL_ERROR);
        }
        return insertOrUpdate(sniffSql.getDbName(), sniffSql.getSql(), contents);
    }

    private static JSONObject selectOne(String dbName, String sql, ContentDTO... contents) {
        List<JSONObject> list = select(dbName, sql, contents);
        return list.size() > 0 ? list.get(0) : new JSONObject();
    }

    private static List<JSONObject> select(String dbName, String sql, ContentDTO... contents) {
        List<JSONObject> list = new ArrayList<>();
        if (contents.length > 0) {
            for (ContentDTO content : contents) {
                sql = sql.replace("#{" + content.source() + "}", content.target());
            }

            LogUtil.warn("【执行sql】" + sql);
        }
        Connection connection = DBConnection.getConnection(dbName);
        if (Objects.isNull(connection)) {
            LogUtil.error("数据库连接异常");
            throw new RuntimeException("数据库连接异常");
        }
        PreparedStatement ps = null;
        try {
            ps = connection.prepareStatement(sql);
            ResultSet rs = ps.executeQuery();
            ResultSetMetaData metaData = rs.getMetaData();
            while (rs.next()) {
                JSONObject result = new JSONObject();
                for (int i = 1; i <= metaData.getColumnCount(); i++) {
                    result.put(metaData.getColumnLabel(i), rs.getString(i));
                }
                list.add(result);
            }
            rs.close();
        } catch (SQLException e) {
            LogUtil.error(e.getMessage());
            throw new RuntimeException(e);
        } finally {
            try {
                Objects.requireNonNull(ps).close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return list;
    }

    private static Integer insertOrUpdate(String dbName, String sql, ContentDTO... contents) {
        int result;
        if (contents.length > 0) {
            for (ContentDTO content : contents) {
                sql = sql.replace("#{" + content.source() + "}", StringUtils.isNotEmpty(content.target()) ? content.target() : "");
            }
        }
        Connection connection = DBConnection.getConnection(dbName);
        PreparedStatement ps = null;
        try {
            ps = connection.prepareStatement(sql);
            result = ps.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                Objects.requireNonNull(ps).close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
}
